home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Wayzata's Best of Shareware PC/Windows 1
/
Wayzata's Best of Shareware for PC-Windows - Release 1 - Wayzata Technology (1993).iso
/
mac
/
DOS
/
UTILITY
/
LZESHE12
/
UNLZEXE.C
< prev
next >
Wrap
Text File
|
1990-03-29
|
7KB
|
264 lines
/* unlzexe.c
* unlzexe ver 0.2 (PC-VAN UTJ44266 Kou )
* UNLZEXE converts the compressed file by lzexe(ver.0.90,0.91) to the
* UNcompressed executable one.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define FAILURE 1
#define SUCCESS 0
typedef unsigned int WORD;
typedef unsigned char BYTE;
main(int argc,char **argv){
int rdhead(FILE *,int *);
void mkreltbl(FILE *,FILE *,int);
void unpack(FILE *,FILE *);
void wrhead(FILE *);
FILE *ifile,*ofile;
int ver;
printf("UNLZEXE Ver. 0.2\n");
if(argc!=3){
printf("usage:UNLZEXE packedfile unpackedfile");
exit(1);
}
if((ifile=fopen(argv[1],"rb"))==NULL){
printf("'%s' :not found.",argv[1]);
exit(1);
}
if(rdhead(ifile,&ver)!=SUCCESS){
printf("'%s' is not LZEXE file.",argv[1]);
}else {
if((ofile=fopen(argv[2],"w+b"))==NULL){
printf("'%s' :can't open.",argv[2]);
fclose(ifile);
exit(1);
}
printf("file '%s' is compressed by LZEXE Ver. ",argv[1]);
switch(ver){
case 90: printf("0.90\n"); break;
case 91: printf("0.91\n"); break;
}
mkreltbl(ifile,ofile,ver);
unpack(ifile,ofile);
wrhead(ofile);
fclose(ofile);
printf("unpacked file '%s' is generated.\n",argv[2]);
}
fclose(ifile);
}
/*-------------------------------------------*/
static WORD ihead[0x10],ohead[0x10],inf[8];
static WORD allocsize;
static long fpos,loadsize;
/* EXE header test (is it LZEXE file?) */
int rdhead(FILE *ifile ,int *ver){
if(fread(ihead,sizeof ihead[0],0x10,ifile)!=0x10)
return FAILURE;
memcpy(ohead,ihead,sizeof ihead[0] * 0x10);
if(ihead[0]!=0x5a4d || ihead[4]!=2 || ihead[0x0d]!=0)
return FAILURE;
if(ihead[0x0c]==0x1c && memcmp(&ihead[0x0e],"LZ09",4)==0){
*ver=90; return SUCCESS ;
}
if(ihead[0x0c]==0x1c && memcmp(&ihead[0x0e],"LZ91",4)==0){
*ver=91; return SUCCESS ;
}
return FAILURE;
}
/* make relocation table */
void mkreltbl(FILE *ifile,FILE *ofile,int ver) {
void reloc90();
void reloc91();
int i;
allocsize=((ihead[1]+16-1)>>4) + ((ihead[2]-1)<<5) - ihead[4] + ihead[5];
fpos=(long)(ihead[0x0b]+ihead[4])<<4; /* goto CS:0000 */
fseek(ifile,fpos,SEEK_SET);
fread(inf, sizeof inf[0], 0x08, ifile);
ohead[0x0a]=inf[0]; /* IP */
ohead[0x0b]=inf[1]; /* CS */
ohead[0x08]=inf[2]; /* SP */
ohead[0x07]=inf[3]; /* SS */
/* inf[4]:size of compressed load module (PARAGRAPH)*/
/* inf[5]:increase of load module size (PARAGRAPH)*/
/* inf[6]:size of decompressor with compressed relocation table (BYTE) */
/* inf[7]:check sum of decompresser with compressd relocation table(Ver.0.90) */
ohead[0x0c]=0x1c; /* start position of relocation table */
fseek(ofile,0x1cL,SEEK_SET);
switch(ver){
case 90: reloc90(ifile,ofile,fpos);
break;
case 91: reloc91(ifile,ofile,fpos);
break;
}
i=ohead[3]*4+ohead[0x0c];
ohead[4]=((i+0x1ff) & ~0x1ff)>>4;
for(i=0x200-(i & 0x1ff); i>0; i--)
putc(0, ofile);
}
/* for LZEXE ver 0.90 */
void reloc90(FILE *ifile,FILE *ofile,long fpos) {
unsigned int c;
WORD rel_count=0;
WORD rel_item[2]; /* [0]:offset, [1]:segment */
fseek(ifile,fpos+0x19d,SEEK_SET);
/* 0x19d=compressed relocation table address */
for(rel_item[1]=0;rel_item[1]<0x10;rel_item[1]++) {
if((c=getw(ifile))==0)
continue;
else {
for(;c>0;c--) {
rel_item[0]=getw(ifile);
putw(rel_item[0],ofile);
putw(rel_item[1],ofile);
rel_count++;
}
}
}
ohead[3]=rel_count;
}
/* for LZEXE ver 0.91*/
void reloc91(FILE *ifile,FILE *ofile,long fpos) {
WORD span;
WORD rel_count=0;
WORD rel_item[2]; /* [0]:offset, [1]:segment */
fseek(ifile,fpos+0x158,SEEK_SET);
/* 0x158=compressed relocation table address */
rel_item[0]=0; rel_item[1]=0;
for(;;) {
if((span=getc(ifile))==0) {
span=getw(ifile);
if(span==0){
rel_item[1] += 0x0fff;
continue;
} else if(span==1){
break;
}
}
rel_item[0] += span;
rel_item[1] += (rel_item[0] & ~0x0f)>>4;
rel_item[0] &= 0x0f;
putw(rel_item[0],ofile);
putw(rel_item[1],ofile);
rel_count++;
}
ohead[3]=rel_count;
}
/*---------------------*/
typedef struct {
FILE *fp;
WORD buf;
BYTE count;
} bitstream;
void initbits(bitstream *,FILE *);
int getbit(bitstream *);
/*---------------------*/
/* decompressor routine */
void unpack(FILE *ifile,FILE *ofile){
int len;
int span;
long fpos;
bitstream bits;
static BYTE data[0x4500], *p=data;
fpos=(long)(ihead[0x0b]-inf[4]+ihead[4])<<4;
fseek(ifile,fpos,SEEK_SET);
fpos=(long)ohead[4]<<4;
fseek(ofile,fpos,SEEK_SET);
initbits(&bits,ifile);
printf(" unpacking. ");
for(;;){
if(p-data>0x4000){
fwrite(data,sizeof data[0],0x2000,ofile);
p-=0x2000;
memcpy(data,data+0x2000,p-data);
putchar('.');
}
if(getbit(&bits)) {
*p++=getc(ifile);
continue;
}
if(!getbit(&bits)) {
len=getbit(&bits)<<1;
len |= getbit(&bits);
len += 2;
span=getc(ifile) | 0xff00;
} else {
span=(BYTE)getc(ifile);
len=getc(ifile);
span |= ((len & ~0x07)<<5) | 0xe000;
len = (len & 0x07)+2;
if (len==2) {
len=getc(ifile);
if(len==0)
break;
if(len==1)
continue; /* segment change */
else
len++;
}
}
for( ;len>0;len--,p++){
*p=*(p+span);
}
}
if(p!=data)
fwrite(data,sizeof data[0],p-data,ofile);
loadsize=ftell(ofile)-fpos;
printf("end\n");
}
/* write EXE header*/
void wrhead(FILE *ofile) {
if(ihead[6]!=0) {
ohead[5]=allocsize-((loadsize+15)>>4);
if(ihead[6]!=0xffff)
ohead[6]-=(ihead[5]-ohead[5]);
}
ohead[1]=(loadsize+(ohead[4]<<4))&0x1ff;
ohead[2]=(loadsize+(ohead[4]<<4)+0x1ff) >>9;
fseek(ofile,0L,SEEK_SET);
fwrite(ohead,sizeof ohead[0],0x0e,ofile);
}
/*-------------------------------------------*/
/* get compress information bit by bit */
void initbits(bitstream *p,FILE *filep){
p->fp=filep;
p->count=0x10;
p->buf=getw(filep);
/* printf("%04x ",p->buf); */
}
int getbit(bitstream *p) {
int b;
b = p->buf & 1;
if(--p->count == 0){
(p->buf)=getw(p->fp);
/* printf("%04x ",p->buf); */
p->count= 0x10;
}else
p->buf >>= 1;
return b;
}